#include <Arduino.h>
#include <U8g2lib.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Wire.h>

#define PAGE_NUM 2
#define BAR_NUM 2

// nodemcu   oled
// 3V3       VDD
// GND       GND
// D1        SCK
// D2        SDA

#define FRESH_TIME 1000

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

const char *ssid = "HUAWEI-34ECZE";
const char *password = "tian7843jing";
const char *host = "api.seniverse.com"; // 将要连接的服务器地址
const int httpPort = 80;                // 将要连接的服务器端口

// 心知天气HTTP请求所需信息
String reqUserKey = "SaTxl0J3xoD3uBrIv"; // 私钥
String reqLocation = "Beijing";          // 城市
String reqUnit = "c";                    // 摄氏
IPAddress local_ip;
WiFiUDP NTP_UDP;
NTPClient time_client(NTP_UDP, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);
HTTPClient http;
String geturl;
String resp;
String date_now;
bool date_geted = false;
unsigned long long time_refresh = 0;
String time_now;
int page_selecter = 0;
int bar_selecter = 0;
String FINAL_TIME = "2022-06-24";
double voltage_support = 0.0; //电源电压
class Button
{
  public:
    Button(int pin);
    bool onDown();

  private:
    bool btn_flag;
    int btn_pin;
};
Button::Button(int pin)
{
  btn_pin = pin;
  btn_flag = true;
}
bool Button::onDown()
{
  bool res = false;
  if (digitalRead(btn_pin) == HIGH)
  {
    delay(20);
    if (digitalRead(btn_pin) == HIGH && btn_flag)
      res = true;
    btn_flag = false;
  }
  else
    btn_flag = true;
  return res;
}

void WiFi_connect() // wifi初始化
{
  WiFi.begin(ssid, password);
  u8g2.setCursor(13, 15);
  int cnt = 1;
  u8g2.setFont(u8g2_font_wqy16_t_chinese3); // use chinese2 for all the glyphs of "你好世界"
  u8g2.setFontDirection(0);
  u8g2.clearBuffer();
  u8g2.setCursor(15, 15);
  Serial.println("WiFi Connecting......");
  u8g2.print("WiFi Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);

    u8g2.setCursor(5 + 12 * (cnt++), 25);
    u8g2.print(".");
    u8g2.sendBuffer();
  }
  // Serial.println("");
  // Serial.println("WiFi Connected!");
  // u8g2.print("WiFi Connected!");
  // u8g2.sendBuffer();
  // Serial.print("IP:");
  local_ip = WiFi.localIP();
  Serial.println(local_ip);
  delay(1000);
  time_client.begin();
  u8g2.clearBuffer();
}
void print_ip()
{
  u8g2.setCursor(5, 15);
  u8g2.setFont(u8g2_font_wqy12_t_chinese3);
  u8g2.print(local_ip);
  //u8g2.sendBuffer();
}

void print_date(String d)
{
  u8g2.setCursor(5, 15);
  u8g2.setFont(u8g2_font_wqy12_t_chinese3);
  u8g2.print(d);
  //u8g2.sendBuffer();
}
void print_week(String w)
{
  u8g2.setCursor(105, 15);
  u8g2.setFont(u8g2_font_wqy12_t_chinese3);
  u8g2.print(w);
  //u8g2.sendBuffer();
}
void print_voltage(double v)
{
  u8g2.setCursor(105, 15);
  u8g2.setFont(u8g2_font_wqy12_t_chinese3);
  u8g2.print(String(v, 1) + "V");
  //u8g2.sendBuffer();
}
String json_split(String json_data)
{
  DynamicJsonDocument doc(1024);
  deserializeJson(doc, json_data);
  JsonObject obj = doc.as<JsonObject>();
  String date = obj["sysTime2"];
  date = date.substring(0, 10);
  Serial.println(date);
  return date;
}
String get_date()
{
  int httpCode = http.GET();

  if (httpCode > 0)
  {

    Serial.printf("[HTTP] GET... code: %d\n", httpCode);

    if (httpCode == HTTP_CODE_OK)
    {

      //读取响应内容

      resp = http.getString();

      Serial.println(resp);
      date_geted = true;
    }
  }
  else
  {

    Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    http.end();
    return "获取天气失败！";
  }
  http.end();
  return json_split(resp);
}
String get_week(String date)
{
  int year = date.substring(0, 4).toInt(), month = date.substring(5, 7).toInt(), day = date.substring(8, 10).toInt();
  int c, y, week;
  if (month == 1 || month == 2)
  {
    year--;
    month += 12;
  }

  c = year / 100;
  y = year - c * 100;
  week = (c / 4) - 2 * c + (y + y / 4) + (13 * (month + 1) / 5) + day - 1;

  while (week < 0)
  {
    week += 7;
  }
  String wk[] = {"Sun", "Mon", "Tur", "Wed", "Thu", "Fri", "Sat"};
  week %= 7;
  return wk[week];
}

bool refreshable(String t)
{
  t = t.substring(3, 8);
  return t == "00:00";
}

void setup(void)
{
  pinMode(D5, INPUT);
  delay(500);
  Serial.begin(9600);
  u8g2.begin();
  u8g2.enableUTF8Print();
  WiFi_connect();
  geturl = "http://quan.suning.com/getSysTime.do";
  http.setTimeout(5000);
  http.begin(geturl);
}
Button btn_page(D5);
Button btn_bar(D4);
void page1()
{
  // Serial.println("Page 1");
  //if(btn2.onDown()) Serial.println("FUCK CCF!");
  if (!date_geted)
  {
    date_now = get_date();
  }
  time_client.update();
  u8g2.setFont(u8g2_font_fub20_tn);
  u8g2.setFontDirection(0);

  u8g2.setCursor(10, 45);
  if (millis() - time_refresh >= FRESH_TIME)
  {
    time_now = time_client.getFormattedTime();
    u8g2.print(time_now);
  }

  print_countdown(date_now);
  // Serial.println(date_now);
  //u8g2.sendBuffer();
  // delay(1000);
  if (refreshable(time_now))
    date_geted = false;
  // if (btn.onDown()) Serial.println("down!");
}
void page2()
{
  // Serial.println("Page 2");
  u8g2.setFont(u8g2_font_fub20_tn);
  u8g2.setFontDirection(0);

  u8g2.setCursor(50, 45);
  if (millis() - time_refresh >= FRESH_TIME)
  {
    time_now = time_client.getFormattedTime();
    u8g2.print("Page 2!");
  }
  u8g2.sendBuffer();
}

bool isLeapYear(int year)
{
  return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}

int getDays(int year, int month, int day)
{
  int m[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  if (isLeapYear(year))
    m[2]++;
  int result = 0;
  for (int i = 1; i < year; i++)
  {
    result += 365;
    if (isLeapYear(i))
      result++;
  }
  for (int i = 1; i < month; i++)
  {
    result += m[i];
  }
  result += day;

  return result;
}
int dayDis(String date1, String date2)
{
  int year1 = date1.substring(0, 4).toInt(),
      month1 = date1.substring(5, 7).toInt(),
      day1 = date1.substring(8, 10).toInt(),
      year2 = date2.substring(0, 4).toInt(),
      month2 = date2.substring(5, 7).toInt(),
      day2 = date2.substring(8, 10).toInt();
  // Serial.println(FINAL_TIME);
  // Serial.printf("%d,%d,%d %d,%d,%d\n",year1,month1,day1,year2,month2,day2);
  return abs(getDays(year2, month2, day2) - getDays(year1, month1, day1));
}
void print_countdown(String d)
{
  u8g2.setCursor(17, 60);
  u8g2.setFont(u8g2_font_wqy12_t_gb2312);
  String s1 = "距离中考还有", s2 = "天";
  u8g2.print(s1 + dayDis(d, FINAL_TIME) + s2);
}
void bar1()
{
  //Serial.println("bar1");
  print_date(date_now);
  print_week(get_week(date_now));
}
void bar2()
{
  //Serial.println("bar2");
  print_ip();
  print_voltage(voltage_support);
}
void (*page[PAGE_NUM])() = {page1, page2};
void (*bar[BAR_NUM])() = {bar1, bar2};
void loop(void)
{
  u8g2.clearBuffer();
  if (btn_page.onDown())
    page_selecter = (page_selecter + 1) % PAGE_NUM;
  if (btn_bar.onDown()) bar_selecter = (bar_selecter + 1) % BAR_NUM;
  bar[bar_selecter]();
  page[page_selecter]();
  u8g2.sendBuffer();
  
}
